<template>
  <div class="app-container">
    <el-row :gutter="20">
      <el-col :span="8">
        <div class="stat-card">
          <el-statistic title="常量路由数量" :value="constantRoutesCount" />
        </div>
      </el-col>
      <el-col :span="8">
        <div class="stat-card">
          <el-statistic title="动态路由数量" :value="dynamicRoutesCount" />
        </div>
      </el-col>
      <el-col :span="8">
        <div class="stat-card">
          <el-statistic title="总路由数量" :value="totalRoutesCount" />
        </div>
      </el-col>
    </el-row>

    <div class="route-trees-container">
      <div class="route-tree-section">
        <h3 class="tree-title">常量路由</h3>
        <el-tree
          ref="constantTree"
          :data="constantRoutesData"
          :props="defaultProps"
          :expand-on-click-node="false"
          :default-expand-all="false"
          :render-content="renderContent"
          :loading="loading"
        >
        </el-tree>
      </div>

      <div class="route-tree-section">
        <h3 class="tree-title">动态路由</h3>
        <el-tree
          ref="dynamicTree"
          :data="dynamicRoutesData"
          :props="defaultProps"
          :expand-on-click-node="false"
          :default-expand-all="false"
          :render-content="renderContent"
          :loading="loading"
        >
        </el-tree>
      </div>
    </div>

    <!-- 路由详情抽屉 -->
    <el-drawer
      title="路由详情"
      :visible.sync="detailVisible"
      direction="rtl"
      size="60%"
    >
      <div class="route-detail">
        <h3>{{ selectedRoute.name || '未命名路由' }}</h3>
        <el-descriptions column="1">
          <el-descriptions-item label="路径">
            <code>{{ selectedRoute.path }}</code>
          </el-descriptions-item>
          <el-descriptions-item label="名称">
            {{ selectedRoute.name || '-' }}
          </el-descriptions-item>
          <el-descriptions-item label="组件">
            <code>{{ getComponentName(selectedRoute) }}</code>
          </el-descriptions-item>
          <el-descriptions-item label="重定向">
            {{ selectedRoute.redirect || '-' }}
          </el-descriptions-item>
          <el-descriptions-item label="隐藏">
            {{ selectedRoute.hidden ? '是' : '否' }}
          </el-descriptions-item>
          <el-descriptions-item label="总是显示">
            {{ selectedRoute.alwaysShow ? '是' : '否' }}
          </el-descriptions-item>
          <el-descriptions-item label="元信息">
            <pre>{{ formatMeta(selectedRoute.meta) }}</pre>
          </el-descriptions-item>
          <el-descriptions-item label="子路由数量">
            {{ selectedRoute.children ? selectedRoute.children.length : 0 }}
          </el-descriptions-item>
          <el-descriptions-item label="权限">
            <div v-if="hasPermission(selectedRoute)">
              <div v-if="selectedRoute.meta && selectedRoute.meta.roles">
                <span class="permission-tag" v-for="role in selectedRoute.meta.roles" :key="role">
                  {{ role }}
                </span>
              </div>
              <div v-else-if="selectedRoute.meta && selectedRoute.meta.permissions">
                <span class="permission-tag" v-for="perm in selectedRoute.meta.permissions" :key="perm">
                  {{ perm }}
                </span>
              </div>
            </div>
            <span v-else>-</span>
          </el-descriptions-item>
        </el-descriptions>
      </div>
    </el-drawer>
  </div>
</template>

<script>
import { constantRoutes } from '@/router';

export default {
  name: 'RouteMonitor',
  data() {
    return {
      // 遮罩层
      loading: true,
      // 查询参数
      queryParams: {
        path: '',
        name: '',
        type: ''
      },
      // 路由树配置
      defaultProps: {
        children: 'children',
        label: 'path'
      },
      // 常量路由
      constantRoutesData: [],
      // 动态路由
      dynamicRoutesData: [],
      // 详情抽屉显示状态
      detailVisible: false,
      // 选中的路由
      selectedRoute: {}
    };
  },
  computed: {
    // 常量路由数量
    constantRoutesCount() {
      return this.countRoutes(this.constantRoutesData);
    },
    // 动态路由数量
    dynamicRoutesCount() {
      return this.countRoutes(this.dynamicRoutesData);
    },
    // 总路由数量
    totalRoutesCount() {
      return this.constantRoutesCount + this.dynamicRoutesCount;
    }
  },
  created() {
    this.refreshRoutes();
  },
  methods: {
    // 刷新路由数据
    refreshRoutes() {
      this.loading = true;
      try {
        // 获取常量路由
        this.constantRoutesData = JSON.parse(JSON.stringify(constantRoutes));
        // 获取所有路由（包括动态添加的）
        const allRoutes = this.$router.options.routes;
        // 从router实例获取实际的路由配置（包括通过addRoutes添加的动态路由）
        const actualRoutes = this.getActualRoutes();

        this.dynamicRoutesData = actualRoutes.filter(route => {
          // 过滤掉常量路由
          return !this.isConstantRoute(route.path);
        });

        this.handleQuery();
      } finally {
        this.loading = false;
      }
    },

    // 获取实际路由配置（包括动态添加的路由）
    getActualRoutes() {
      // 方法1：从router.options.routes中获取基础路由
      // 方法2：递归遍历router.matcher获取所有路由记录
      const routes = [];
      const traverseRoutes = (matcher) => {
        if (matcher.path) {
          routes.push({
            path: matcher.path,
            name: matcher.name,
            component: matcher.components ? matcher.components.default : null,
            redirect: matcher.redirect,
            meta: matcher.meta || {},
            hidden: matcher.meta ? matcher.meta.hidden : false,
            alwaysShow: matcher.meta ? matcher.meta.alwaysShow : false,
            children: []
          });
        }
        if (matcher.children) {
          matcher.children.forEach(child => traverseRoutes(child));
        }
      };

      // 遍历matcher
      if (this.$router.matcher && this.$router.matcher.match) {
        const matchers = this.getMatchers(this.$router.matcher);
        matchers.forEach(matcher => traverseRoutes(matcher));
      }

      // 方法3：使用store中的权限路由（如果有）
      if (this.$store && this.$store.getters && this.$store.getters.permission_routes) {
        const storeRoutes = this.$store.getters.permission_routes;
        // 合并store中的路由和已获取的路由
        storeRoutes.forEach(route => {
          if (!routes.some(r => r.path === route.path)) {
            routes.push(route);
          }
        });
      }

      return routes;
    },

    // 获取matcher数组
    getMatchers(matcher) {
      const matchers = [];
      if (matcher.children) {
        matcher.children.forEach(child => {
          matchers.push(child);
          matchers.push(...this.getMatchers(child));
        });
      }
      return matchers;
    },

    // 判断是否为常量路由
    isConstantRoute(path) {
      return constantRoutes.some(route => route.path === path);
    },

    /** 查询按钮操作 */
    handleQuery() {
      const { path, name, type } = this.queryParams;

      // 如果有类型过滤
      if (type === 'constant') {
        this.filterRoutes(this.constantRoutesData, path, name);
      } else if (type === 'dynamic') {
        this.filterRoutes(this.dynamicRoutesData, path, name);
      } else {
        // 不过滤类型，对两种路由都进行过滤
        this.filterRoutes(this.constantRoutesData, path, name);
        this.filterRoutes(this.dynamicRoutesData, path, name);
      }
    },

    // 过滤路由
    filterRoutes(routesData, path, name) {
      if (!routesData) return;

      const filterChildren = (children) => {
        if (!children) return null;

        const filtered = children.map(child => {
          const matchPath = !path || child.path.toLowerCase().includes(path.toLowerCase());
          const matchName = !name || (child.name && child.name.toLowerCase().includes(name.toLowerCase()));

          // 检查子路由
          const filteredChildren = filterChildren(child.children);

          // 匹配当前路由或子路由有匹配项
          if (matchPath || matchName || (filteredChildren && filteredChildren.length > 0)) {
            return {
              ...child,
              children: filteredChildren
            };
          }
          return null;
        }).filter(Boolean);

        return filtered.length > 0 ? filtered : null;
      };

      // 过滤根级路由
      const filteredRoutes = routesData.filter(route => {
        const matchPath = !path || route.path.toLowerCase().includes(path.toLowerCase());
        const matchName = !name || (route.name && route.name.toLowerCase().includes(name.toLowerCase()));

        // 检查子路由
        const filteredChildren = filterChildren(route.children);

        // 匹配当前路由或子路由有匹配项
        if (matchPath || matchName || (filteredChildren && filteredChildren.length > 0)) {
          route.children = filteredChildren;
          return true;
        }
        return false;
      });
    },

    /** 重置按钮操作 */
    resetQuery() {
      this.resetForm("queryForm");
      this.refreshRoutes();
    },

    /** 重置表单 */
    resetForm(formName) {
      if (this.$refs[formName]) {
        this.$refs[formName].resetFields();
      }
    },

    // 展开所有节点
    expandAll() {
      this.$nextTick(() => {
        if (this.$refs.constantTree) {
          this.$refs.constantTree.setExpandedKeys(this.getAllNodeKeys(this.constantRoutesData));
        }
        if (this.$refs.dynamicTree) {
          this.$refs.dynamicTree.setExpandedKeys(this.getAllNodeKeys(this.dynamicRoutesData));
        }
      });
    },

    // 折叠所有节点
    collapseAll() {
      this.$nextTick(() => {
        if (this.$refs.constantTree) {
          this.$refs.constantTree.setExpandedKeys([]);
        }
        if (this.$refs.dynamicTree) {
          this.$refs.dynamicTree.setExpandedKeys([]);
        }
      });
    },

    // 获取所有节点的key
    getAllNodeKeys(routes, parentPath = '') {
      let keys = [];

      routes.forEach(route => {
        const path = parentPath ? `${parentPath}-${route.path}` : route.path;
        keys.push(path);

        if (route.children && route.children.length > 0) {
          keys = keys.concat(this.getAllNodeKeys(route.children, path));
        }
      });

      return keys;
    },

    // 渲染节点内容
    renderContent(h, { node, data, store }) {
      const hasChildren = data.children && data.children.length > 0;

      return h('div', {
        class: 'tree-node-content',
        on: {
          click: () => {
            this.showRouteDetail(data);
          }
        }
      }, [
        h('span', { class: 'node-label' }, [
          h('i', { class: `el-icon-${hasChildren ? 'folder-opened' : 'document'}` }),
          h('span', { style: { marginLeft: '8px' } }, [
            data.path
          ])
        ]),
        data.name && h('span', { class: 'node-name' }, `(${data.name})`),
        data.hidden && h('span', { class: 'node-badge hidden-badge' }, '隐藏'),
        data.meta && data.meta.roles && h('span', { class: 'node-badge role-badge' }, '需要权限')
      ]);
    },

    // 显示路由详情
    showRouteDetail(route) {
      this.selectedRoute = route;
      this.detailVisible = true;
    },

    // 获取组件名称
    getComponentName(route) {
      if (typeof route.component === 'string') {
        return route.component;
      } else if (route.component && route.component.name) {
        return route.component.name;
      }
      return 'Function Component';
    },

    // 格式化元信息
    formatMeta(meta) {
      if (!meta) return '{}';
      return JSON.stringify(meta, null, 2);
    },

    // 判断是否有权限信息
    hasPermission(route) {
      return route.meta && (route.meta.roles || route.meta.permissions);
    },

    // 统计路由数量
    countRoutes(routes) {
      let count = 0;

      if (!routes) return 0;

      routes.forEach(route => {
        count++;
        if (route.children && route.children.length > 0) {
          count += this.countRoutes(route.children);
        }
      });

      return count;
    }
  }
};
</script>

<style scoped>
.stat-card {
  background-color: #f5f7fa;
  padding: 20px;
  border-radius: 4px;
  margin-bottom: 20px;
}

.route-trees-container {
  display: flex;
  gap: 20px;
  margin-top: 20px;
}

.route-tree-section {
  flex: 1;
  border: 1px solid #ebeef5;
  border-radius: 4px;
  padding: 15px;
}

.tree-title {
  margin-top: 0;
  margin-bottom: 15px;
  font-size: 16px;
  color: #303133;
}

.el-tree {
  max-height: calc(100vh - 350px);
  overflow-y: auto;
}

.tree-node-content {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 4px 0;
  cursor: pointer;
}

.tree-node-content:hover {
  background-color: #f5f7fa;
}

.node-label {
  display: flex;
  align-items: center;
  flex: 1;
}

.node-name {
  color: #606266;
  font-size: 12px;
}

.node-badge {
  font-size: 11px;
  padding: 2px 6px;
  border-radius: 10px;
  background-color: #f0f2f5;
  color: #606266;
}

.hidden-badge {
  background-color: #fdf6ec;
  color: #e6a23c;
}

.role-badge {
  background-color: #ecf5ff;
  color: #409eff;
}

.route-detail {
  padding: 20px;
}

.route-detail h3 {
  margin-top: 0;
  margin-bottom: 20px;
  color: #333;
}

.route-detail pre {
  background-color: #f5f7fa;
  padding: 10px;
  border-radius: 4px;
  overflow-x: auto;
  margin: 0;
}

.permission-tag {
  display: inline-block;
  background-color: #f0f9eb;
  color: #67c23a;
  padding: 4px 8px;
  border-radius: 4px;
  font-size: 12px;
  margin-right: 8px;
  margin-bottom: 8px;
}

code {
  background-color: #f5f7fa;
  padding: 2px 4px;
  border-radius: 4px;
  font-size: 12px;
}

/* 滚动条样式 */
.el-tree::-webkit-scrollbar {
  width: 8px;
}

.el-tree::-webkit-scrollbar-track {
  background: #f1f1f1;
  border-radius: 4px;
}

.el-tree::-webkit-scrollbar-thumb {
  background: #888;
  border-radius: 4px;
}

.el-tree::-webkit-scrollbar-thumb:hover {
  background: #555;
}
</style>
